/*
 * 代号：凤凰
 * http://www.jphenix.org
 * 2014-06-12
 * V4.0
 */
package com.jphenix.share.tools;

import com.jphenix.standard.docs.ClassInfo;

import java.io.ByteArrayOutputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.util.Enumeration;
import java.util.jar.JarEntry;
import java.util.jar.JarOutputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;

/**
 * 修改指定jar源码包的编码格式
 * 
 * 执行过程中会过滤掉 CVS 和 .svn 文件夹以及里面的所有文件
 * 
 * 
 * 
 * 注意，该类只处理java文件
 * 
 * com.jphenix.share.tools.ChangeJarEncoding
 * @author 刘虻
 * 2011-10-31 下午04:17:08
 */
@ClassInfo({"2014-06-12 20:02","修改指定jar源码包的编码格式"})
public class ChangeJarEncoding {

	protected String 
						srcFilePath 	= null	//源jar文件路径
						,srcEncoding 	= null	//源文件编码
						,objFilePath 	= null	//目标jar文件路径
						,objEncoding 	= null;	//目标文件编码
	
	
	/**
	 * 构造函数
	 * @author 刘虻
	 */
	public ChangeJarEncoding() {
		super();
	}
	
	
	/**
	 * 执行转换
	 * 刘虻
	 * 2011-10-31 下午04:55:22
	 */
	public void execute() {
		
		ZipFile srcFile = null;
		
		//构造文件输出流
		FileOutputStream fout = null;
		try {
			fout = new FileOutputStream(getObjFilePath());
		}catch(Exception e) {
			System.out.println(
					"create FileOutputStream error,path:"+getObjFilePath());
			e.printStackTrace();
			return;
		}
		//构造jar文件输出流
		JarOutputStream jout = null;
		try {
			jout = new JarOutputStream(fout);
		}catch(Exception e) {
			System.out.println(
					"create JarOutputStream error,path:"+getObjFilePath());
			e.printStackTrace();
			try {
				fout.close();
			}catch(Exception ee) {
				ee.printStackTrace();
			}
			return;
		}
		try {
			srcFile = new ZipFile(getSrcFilePath());
			Enumeration<? extends ZipEntry> entries = srcFile.entries();
			while(entries.hasMoreElements()) {
				//获取压缩文件元素
				ZipEntry entry = entries.nextElement();
				//获取压缩文件元素流
				InputStream entryIs = srcFile.getInputStream(entry);
				//输出到目标文件
				outFile(jout,entryIs,entry);
			}
		}catch(Exception e) {
			e.printStackTrace();
		}finally {
			try {
				srcFile.close();
			}catch(Exception e2) {}
			srcFile = null;
			try {
				jout.close();
			}catch(Exception e2) {}
			jout = null;
		}
		System.out.println("Output to File Completed");
	}
	
	
	/**
	 * 输出到文件
	 * 刘虻
	 * 2011-11-1 下午01:20:47
	 * @param jos			jar文件输出流
	 * @param is			源文件读入六
	 * @param entry			源文件元素信息
	 * @throws Exception	异常
	 */
	public void outFile(
			JarOutputStream jos
			,InputStream is
			,ZipEntry entry) throws Exception {
		String filePath = entry.getName(); //文件路径信息
		if(checkSkip(filePath)) {
			return;
		}
		//是否转换编码
		boolean doEncoding =
                (filePath.toLowerCase().endsWith(".java"))
                        || !getSrcEncoding().equals(getObjEncoding());
		JarEntry je = new JarEntry(filePath);
		je.setSize(entry.getSize()); //放入文件大小信息
		je.setTime(entry.getTime()); //放入文件时间
		jos.putNextEntry(je);
		
		//构造缓存
		byte[] buffer = new byte[1024];
		//构造读入字节
		int readByteSize = 0;
		if(doEncoding) {
			ByteArrayOutputStream bos = new ByteArrayOutputStream();
			while ((readByteSize = is.read(buffer)) != -1) {
				bos.write(buffer, 0, readByteSize);
			}
			jos.write(bos.toString(getSrcEncoding()).getBytes(getObjEncoding()));
		}else {
			while ((readByteSize=is.read(buffer))!=-1) {
				jos.write(buffer, 0, readByteSize);
			}
		}
		//关闭流
		is.close();
		//提交
		jos.flush();
		//关闭列表
		jos.closeEntry();
	}
	
	
	/**
	 * 检测是否跳过
	 * 刘虻
	 * 2011-11-1 下午01:34:50
	 * @param path 路径
	 * @return true跳过
	 */
	protected boolean checkSkip(String path) {
		if(path==null) {
			return true;
		}
		path = path.toLowerCase();
        return path.indexOf(".svn/") > -1
                || path.indexOf("cvs/") > -1
                || path.indexOf(".cvsignore") > -1;
    }
	
	
	
	/**
	 * 获取目标文件编码
	 * 刘虻
	 * 2011-10-31 下午05:15:32
	 * @return 目标文件编码
	 */
	public String getObjEncoding() {
		if(objEncoding==null) {
			objEncoding = "GBK";
		}
		return objEncoding;
	}
	
	/**
	 * 设置目标文件编码
	 * 刘虻
	 * 2011-10-31 下午05:15:17
	 * @param objEncoding 目标文件编码
	 */
	public void setObjEncoding(String objEncoding) {
		this.objEncoding = objEncoding;
	}
	
	/**
	 * 获取目标jar文件路径
	 * 刘虻
	 * 2011-10-31 下午05:14:32
	 * @return 目标jar文件路径
	 */
	public String getObjFilePath() {
		if(objFilePath==null) {
			objFilePath = "";
		}
		return objFilePath;
	}
	
	/**
	 * 设置目标jar文件路径
	 * 刘虻
	 * 2011-10-31 下午05:14:02
	 * @param objFilePath 目标jar文件路径
	 */
	public void setObjFilePath(String objFilePath) {
		this.objFilePath = objFilePath;
	}
	
	/**
	 * 获取源文件编码
	 * 刘虻
	 * 2011-10-31 下午05:13:13
	 * @return 源文件编码
	 */
	public String getSrcEncoding() {
		if(srcEncoding==null) {
			srcEncoding = "UTF-8";
		}
		return srcEncoding;
	}
	
	/**
	 * 设置源文件编码
	 * 刘虻
	 * 2011-10-31 下午05:12:30
	 * @param srcEncoding 源文件编码
	 */
	public void setSrcEncoding(String srcEncoding) {
		this.srcEncoding = srcEncoding;
	}
	
	
	/**
	 * 获取源jar文件路径
	 * 刘虻
	 * 2011-10-31 下午04:56:30
	 * @return 源jar文件路径
	 */
	public String getSrcFilePath() {
		if(srcFilePath==null) {
			srcFilePath = "";
		}
		return srcFilePath;
	}
	
	/**
	 * 设置源jar文件路径
	 * 刘虻
	 * 2011-10-31 下午04:56:52
	 * @param srcFilePath 源jar文件路径
	 */
	public void setSrcFilePath(String srcFilePath) {
		this.srcFilePath = srcFilePath;
	}
	
	
	
	/**
	 * 执行入口
	 * 刘虻
	 * 2011-10-31 下午04:28:43
	 * @param arg0 传入参数
	 * 
	 * 0 源jar路径
	 * 1 源jar编码  GBK  UTF-8
	 * 2 目标jar路径
	 * 3 目标jar编码 GBK UTF-8
	 */
	public static void main(String[] arg0) {
		
		/*
		//测试参数
		arg0 = new String[4];
		arg0[0] = "d:/phenix_sdk_src.jar";
		arg0[1] = "UTF-8";
		arg0[2] = "d:/phenix_sdk_src_gbk.jar";
		arg0[3] = "GBK";
		*/
		if(arg0==null || arg0.length<4) {
			System.out.println(help());
			return;
		}
		//构建类实例
		ChangeJarEncoding cje = new ChangeJarEncoding();
		
		cje.srcFilePath = arg0[0];
		cje.srcEncoding = arg0[1];
		cje.objFilePath = arg0[2];
		cje.objEncoding = arg0[3];
		
		cje.execute(); //执行转换
	}
	
	
	/**
	 * 输出帮助信息
	 * 刘虻
	 * 2011-10-31 下午04:47:00
	 * @return 帮助信息
	 */
	public static String help() {
		return "<src jar file path> <src jar encoding> <obj jar file path> <obj jar encoding>";
	}
}
